package com.SpringMVC.simulation;

import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SourceFilteringListener;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.HttpServletBean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 41579 on 2017/5/5.
 * 模拟DispatcherServlet加载web组件到HandlerMapping
 */
public class SimulationDispatcherServlete extends HttpServletBean {
    private String contextConfigLocation;
    private List<HandlerMapping> handlerMappings = new ArrayList<HandlerMapping>();

    @Override
    public void initServletBean() {
//        System.out.println(this.contextConfigLocation);
//        ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(XmlWebApplicationContext.class);
//        wac.setConfigLocation(this.contextConfigLocation);
//        wac.setEnvironment(new StandardServletEnvironment());
//        wac.addApplicationListener(new SourceFilteringListener(wac, new TestServlete.TestContextListener()));
//        wac.refresh();

        ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(AnnotationConfigWebApplicationContext.class);
        wac.setConfigLocation(this.contextConfigLocation);
        wac.setEnvironment(new StandardServletEnvironment());
        wac.addApplicationListener(new SourceFilteringListener(wac, new SimulationDispatcherServlete.TestContextListener()));
        wac.refresh();


    }

    public String getContextConfigLocation() {
        return contextConfigLocation;
    }

    public void setContextConfigLocation(String contextConfigLocation) {
        this.contextConfigLocation = contextConfigLocation;
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("");
    }

    public void service(HttpServletRequest request, HttpServletResponse response){
        SimulationRequestHandlerMapping handlerMapping = (SimulationRequestHandlerMapping) handlerMappings.get(0);
        HandlerExecutionChain handlerExecutionChain = null;
        try {
            handlerExecutionChain = handlerMapping.getHandler(request);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Object handler =  handlerExecutionChain.getHandler();
        Method method = handlerMapping.getHandlerMethods().get(request.getServletPath()).getMethod();
        try {
            method.invoke(handler,"fds","123");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public class TestContextListener implements ApplicationListener<ContextRefreshedEvent> {

        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            HandlerMapping handlerMapping = contextRefreshedEvent.getApplicationContext().getBean("simulationHandlerMapping", HandlerMapping.class);
            handlerMappings.add(handlerMapping);
        }
    }
}
